/**
  * Author: Mei
  * Date: 2021-01-10 10:22
  * Description: 将各种可调用对象转换为function
  *
  */
#include "../head.h"
#include <stdio.h>

template<typename Function>
struct function_traits : public function_traits<decltype(&Function::operator())> { //是一个const类型
    function_traits() {
        cout << "general template" << endl;
        //&Function::operator()(2, 3);
        //decltype(&Function::operator()) fun;
        //fun(2,3);
        printf("%p\n", Function::operator());
        //Function::operator()(1, 5);
        //ff(2,3);
        decltype(Function::operator()) ff;
        //ff->* (2,3);

        printf("%p\n", ff);


        //Function::operator()(2,3);
        cout <<"address: "<< &Function::operator() << endl;
    }
};

template<typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType (ClassType::*)(Args...) const> {
    void show() {
        ReturnType a = 20;
        cout << a << endl;
        cout << "size: " << sizeof...(Args) << endl;
    }

    function_traits() {
        cout << "special template" << endl;
        //ClassType::operator()(2,3);
    }

    typedef function<ReturnType(Args...)> function;  //编译器推导好智能
};

template<typename Function>
typename function_traits<Function>::function
to_function(Function &&lambda) {
    function_traits<Function> fun;
    fun.show();

    return static_cast<typename function_traits<Function>::function>(lambda);
}

template<typename Range, typename Fun>
void select(Range range, Fun &f) {
    auto fn = to_function(forward<Fun>(f));
    fn(range, range);
}

int main4() {
    auto fn =  [](int i, int j) {
        cout << 20 + i << endl;
        return i + j;
    };
    select(2, fn);
    return 0;
}